home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
039a
/
szml2src.zip
/
SIZML200.C
< prev
Wrap
C/C++ Source or Header
|
1991-01-01
|
20KB
|
595 lines
/****************************************************************************
* Sizml200.c - 12/31/90 *
* *
* Sizml200 is based on the original work of Bob Hartman. Portions of this *
* program are (C) Copyright 1990-91 Bill Weinel and may not be modified or *
* distributed (except as originally provided) without my expressed written *
* permission. Sizml200 MUST BE distributed FREE OF CHARGE and unmodified as *
* originally provided. It may not be offered for sale in any shape or form *
* as part of any package or of program collection. *
* *
* The original Sizml200.Lzh package was compiled with MS Quick C v2.00. *
* Due to stack space limitations compile with QCL only (except for DEBUG). *
* QCL compile command used to make Sizml200: *
* *
* QCL /AC /Gt256 /F 6000 /Ot sizml200.c *
* *
* Possible future enhancements: *
* - using the heap for struct & variable storage to cut stack space usage *
* - cleaning up and repetitive sections into functions. *
* *
****************************************************************************/
/* Include headers */
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include <stdlib.h>
/* If debugging is necessary.. you may uncomment this to test with small */
/* file sets. (ie: 10 nodes or less). This allows testing with the QCE /*
/* #define DEBUGS */ /* trims size of buffers, nodes for debug */
/* Global variables & structs */
typedef struct {
int zone; /* zone number */
int net; /* net number */
int node; /* node number */
long size; /* packet size */
char hold[80]; /* hold area */
} NODELIST, *NODELISTP;
#ifdef DEBUGS
NODELIST nodes[10]; /* small list for testing */
#else
NODELIST nodes[500]; /* allow for 500 nodes */
#endif
int n_nodes;
char drive1[_MAX_DRIVE];
char dir1[_MAX_DIR];
char fname1[_MAX_FNAME];
char ext1[_MAX_EXT];
char drive2[_MAX_DRIVE];
char dir2[_MAX_DIR];
char fname2[_MAX_FNAME];
char ext2[_MAX_EXT];
char cfg_file[100]; /* user defined cfg file name */
char qflag_file[100]; /* used for qm multitaking flags */
char move_name[100]; /* move area name */
char outbound_name[100]; /* old outbound area name */
char outbnd_name[100]; /* new outbound area name */
char hold_name[100];
char temp_name[100];
char flo1_name[100];
char flo2_name[100];
char test_name[100]; /* drive test name */
char bflag_name[100]; /* binkley flag path */
char send_files[100][100];
int myzone = -1000;
int mynet = -1000;
int mynode = -1000;
char *REV = "$Revision: 2.00 $"; /* Sizemail revision number */
char *str_to_upper(char *p) /* convert a string to upper */
{
char *pt; /* temp head pointer */
pt = p; /* save head pointer */
if (p != NULL) /* if valid.. convert */
{
for(; *p != '\0'; p++)
*p = toupper(*p);
return(pt);
}
else /* otherwise.. return */
return (NULL);
}
void main (int argc, char *argv[])
{
int i, j, k, length, f1, fi, fo;
int done = 0; /* ?lo done flag */
int done_node = 0; /* node done flag */
int move_flag = 0; /* move|copy flag */
int usr_cfg = 0; /* user cfg file */
int flags = 0; /* flag file mode */
int all = 0; /* all files mode */
int multtsk = 0; /* multitask mode */
int inf_level = 2; /* info level default*/
int ndflag = 0; /* node hdr display flag */
int idflag = 0; /* indent display flag */
char infolev[2]; /* info level cmd */
char buff[256]; /* cfg file buffer */
char *p, *p1, *p2, *p3, *p4, *p5, *p6; /* string pointers */
char buff1[20], buff2[20]; /* Junk buffers */
FILE *f;
struct find_t abuffer, fbuffer, qflbuffer, bflbuffer;
#ifdef DEBUGS
char dskbuf[256]; /* test file copy buffer */
#else
char dskbuf[16392]; /* file copy buffer */
#endif
sscanf (REV, "$%s %s", buff1, buff2);
printf ("\nSizeMail - %s %s %s %s\n", buff1, buff2, __DATE__, __TIME__);
printf (" original code by Bob Hartman, Bit Bucket Software\n");
printf (" updated by Bill Weinel of 1:151/121@Fidonet.org\n");
printf (" portions (C) Copyright 1990-91 Bill Weinel\n\n");
/* parse command line */
i=0;
while ((i+1) != argc)
{
i++;
if (strcmp(argv[i],"?") == 0) /* show help */
{
printf ("\n Usage: Sizemail [-cuser.cfg] [-fflags.dir] [-b] [-vx] [-a] [?]\n\n");
printf (" where:\n");
printf (" -cuser.cfg is a user defined cfg file\n");
printf (" (if not specified defaults to SIZEMAIL.CFG)\n");
printf (" -fflags.dir uses QM multitasking flag directory\n");
printf (" -b uses Binkley multitasking mode\n");
printf (" -vx is verbose level\n");
printf (" where x is:\n");
printf (" 0 - nothing displayed\n");
printf (" 1 - only significant processing displayed\n");
printf (" 2 - all processing displayed\n");
printf (" -a is move all mode\n");
printf (" ? displays help\n\n");
exit(0);
}
else if (strncmp(argv[i],"-a",2) == 0) /* set move all mode */
{
all = 1;
}
else if (strncmp(argv[i],"-b",2) == 0) /* set multitask mode */
{
multtsk = 1;
}
else if (strncmp(argv[i],"-v",2) == 0) /* set verbose level */
{
p = strpbrk(argv[i],"v") + 1;
strcpy(infolev, p); /* get verbosity level */
switch (infolev[0]) /* convert it to a flag */
{
case '0': inf_level = 0;
break;
case '1': inf_level = 1;
break;
case '2': inf_level = 2;
break;
default: inf_level = 2; /* default level */
}
}
else if (strncmp(argv[i],"-f",2) == 0) /* set flagged mode */
{
flags = 1;
p = strpbrk(argv[i],"f") + 1;
strcpy(qflag_file, str_to_upper(p)); /* get user flags dir name */
}
else if (strncmp(argv[i],"-c",2) == 0) /* read specified cfg file */
{
usr_cfg = 1; /* set user defined cfg flag */
p = strpbrk(argv[i],"c") + 1;
strcpy(cfg_file, str_to_upper(p)); /* get user cfg file name */
}
} /* end while */
if (!usr_cfg) /* did we have a user defined cfg? */
{ /* no use default */
if ((f = fopen ("SIZEMAIL.CFG", "r")) == NULL)
{
printf ("Error: Cannot open SizeMail.Cfg - aborting\n");
exit (1);
}
} /* yep go get it */
else if ((f = fopen (cfg_file, "r")) == NULL)
{
printf ("Error: Cannot open %s - aborting\n", cfg_file);
exit (1);
}
/* read & parse cfg file */
while (str_to_upper(fgets (buff, 256, f)) != NULL)
{
if (strnicmp (buff, "NODE", 4) == 0)
{
sscanf (&buff[4], "%d:%d/%d", &myzone, &mynet, &mynode);
}
else if (strnicmp (buff, "OUTBOUND", 8) == 0)
{
sscanf (&buff[8], "%s", outbound_name);
strcpy (outbnd_name, outbound_name); /* save for later */
strcpy (temp_name, outbound_name);
strcpy (flo1_name, outbound_name);
strcpy (flo2_name, outbound_name);
strcpy (bflag_name, outbound_name);
/* point to end of each string */
p = &(outbound_name[strlen(outbound_name)]);
p2 = &(temp_name[strlen(temp_name)]);
p3 = &(flo1_name[strlen(flo1_name)]);
p4 = &(flo2_name[strlen(flo2_name)]);
p5 = &(qflag_file[strlen(qflag_file)]);
p6 = &(bflag_name[strlen(bflag_name)]);
}
else if (strnicmp (buff, "SIZE", 4) == 0)
{
sscanf (&buff[4], "%d:%d/%d %ld %s", &(nodes[n_nodes].zone),
&(nodes[n_nodes].net),
&(nodes[n_nodes].node),
&(nodes[n_nodes].size),
(nodes[n_nodes].hold));
++n_nodes;
}
}
fclose (f);
/* weed out the bad errors first */
if ((myzone == -1000) || (mynet == -1000) || (mynode == -1000))
{
printf ("Error: No valid zone:net/node number for this node - aborting\n");
exit (1);
}
if (outbound_name[0] == '\0')
{
printf ("Error: No outbound area defined for this node - aborting\n");
exit (1);
}
/* Run through each zone:net/node to find arcmail file */
for (i = 0; i < n_nodes; i++)
{
ndflag = 0; /* reset nd hdr display flag */
idflag = 0; /* reset indent flag */
if (inf_level >= 2)
{
ndflag = 1; /* show we displayed it */
printf ("Node %d:%d/%d", nodes[i].zone, nodes[i].net, nodes[i].node);
}
if (myzone != nodes[i].zone) /* point to outbound */
{
sprintf (p, ".%03d\\%04x%04x.*", nodes[i].zone,
mynet - nodes[i].net, mynode - nodes[i].node);
if (multtsk) /* setup binkley flag pointer */
sprintf (p6, ".%03d\\%04x%04x.BSY", nodes[i].zone,
nodes[i].net, nodes[i].node);
}
else
{
sprintf (p, "\\%04x%04x.*",
mynet - nodes[i].net, mynode - nodes[i].node);
if (multtsk) /* setup binkley flag pointer */
sprintf (p6, "\\%04x%04x.BSY", nodes[i].net, nodes[i].node);
}
/* If file doesn't exist, just continue */
if (_dos_findfirst (outbound_name, _A_NORMAL, &abuffer))
{
if (inf_level >= 2)
printf ("\t-None found\n"); /* terminate line and continue */
continue;
}
done_node = 0; /* else set up loop to check for a nodes files */
while (!done_node)
{
/* if we need to adjust line starting point */
if ((inf_level >= 1) && (idflag == 1))
{
printf (" ");
}
/* If size of file is less than threshold, continue */
if ((abuffer.size < nodes[i].size) && (!all))
{
if (inf_level >= 2)
{
printf ("\t-Leaving mail of size %ld < %ld threshold\n", abuffer.size, nodes[i].size);
idflag = 1; /* if there's more than one, we need to indent */
}
/* get the next file for this node number */
if (_dos_findnext (&abuffer))
{
/* if we indented we need to adjust line starting point */
if ((inf_level >= 1) && (idflag == 1))
printf ("\r");
done_node = 1;
}
continue; /* then drop to loop */
}
/* if file size is 0 and move all is set.. don't move */
if ((abuffer.size < 1) && (all))
{
if (inf_level >= 2)
{
printf ("\t-Leaving mail of size %ld\n", abuffer.size);
idflag = 1; /* if there's more than one, we need to indent */
}
/* get the next file for this node number */
if (_dos_findnext (&abuffer))
{
/* if we indented we need to adjust line starting point */
if ((inf_level >= 1) && (idflag == 1))
printf ("\r");
done_node = 1;
}
continue; /* then drop to loop */
}
/* Check to see if a Flag file exists for node */
/* If so, then do not change their mail */
/* otherwise, create file, then delete it after processing */
if (flags) /* do QM style multitasking check */
{
sprintf (p5, "\\%04x%04x.%03x", nodes[i].net,
nodes[i].node, nodes[i].zone);
if (_dos_findfirst (qflag_file, _A_NORMAL, &qflbuffer) == 0) /* Found it */
{
if (inf_level >= 2)
printf ("\t-QM is currently processing mail - NOT MOVING!\n");
done_node = 1;
continue; /* drop to loop */
}
/* Create the Flag file */
/* BEGIN CRITICAL QM CODE SECTION */
if ((f = fopen (qflag_file, "ab")) != NULL)
{
fclose (f);
}
} /* end if flags */
/* Check to see if a Binkley style flag file exists for node */
/* If so, then do not change their mail */
/* otherwise, create file, then delete it after processing */
if (multtsk)
{
if (_dos_findfirst (bflag_name, _A_NORMAL, &bflbuffer) == 0) /* Found it */
{
if (inf_level >= 2)
printf ("\t-Binkley currently processing mail - NOT MOVING!\n");
done_node = 1;
continue; /* drop to loop */
}
/* Create the Binkley flag file */
/* BEGIN CRITICAL BINKLEY CODE SECTION */
if ((f = fopen (bflag_name, "ab")) != NULL)
{
fclose (f);
}
} /* end if mttsk */
if ((inf_level >= 1) && (!ndflag))
{
ndflag = 1;
printf ("Node %d:%d/%d", nodes[i].zone, nodes[i].net, nodes[i].node);
}
/* determine where we are going to save it */
strcpy(test_name, nodes[i].hold); /* get name to test */
if ((strlen(nodes[i].hold) >= 2) &&
(strncmp(outbnd_name, test_name, 2)) != 0)
{
move_flag = 1; /* show we are copying */
strcpy(hold_name, nodes[i].hold);
}
else if (nodes[i].hold[0] == '\0')
{
move_flag = 0;
strcpy (hold_name, outbnd_name);
}
else
{
move_flag = 0; /* show we are renaming */
strcpy (hold_name, outbnd_name);
}
p1 = &(hold_name[strlen(hold_name)]);
sprintf (p1, ".TMP");
mkdir (hold_name);
/* Create hold area name */
sprintf (p1, ".TMP\\%s", abuffer.name);
/* Create actual file name */
if (myzone != nodes[i].zone)
{
sprintf (p2, ".%03d\\%s", nodes[i].zone, abuffer.name);
sprintf (p3, ".%03d\\%04x%04x.?LO", nodes[i].zone, nodes[i].net, nodes[i].node);
}
else
{
sprintf (p2, "\\%s", abuffer.name);
sprintf (p3, "\\%04x%04x.?LO", nodes[i].net, nodes[i].node);
}
/* Move or copy file to holding area */
if (move_flag)
{
if (inf_level >= 1) /* display area name */
{
printf ("\t-Copying %s [%ldb] -> %s\n", (p+1), abuffer.size, hold_name);
idflag = 1; /* ok to indent */
}
/* Open input file for read */
if ((fi = open (temp_name, O_BINARY|O_RDONLY, S_IREAD)) == -1)
{
printf ("\nError: Cannot open %s - aborting\n", temp_name);
if (multtsk) unlink (bflag_name);
if (flags) unlink (qflag_file);
exit (1);
}
/* Open output file for write */
if ((fo = open (hold_name, O_CREAT|O_WRONLY|O_BINARY, S_IWRITE)) == -1)
{
printf ("\nError: Cannot open %s - aborting\n", hold_name);
if (multtsk) unlink (bflag_name);
if (flags) unlink (qflag_file);
exit (1);
}
#ifdef DEBUGS
while (length = read (fi, dskbuf, 256)) /* small tst buf copy */
#else
while (length = read (fi, dskbuf, 16392)) /* production copy */
#endif
{
if ((write (fo, dskbuf, length)) == -1)
{
printf ("\nError: Cannot write %s - aborting\n", hold_name);
if (multtsk) unlink (bflag_name);
if (flags) unlink (qflag_file);
exit(1);
}
}
if (close (fi) == -1)
{
printf ("\nError: Cannot close %s - aborting\n", temp_name);
if (multtsk) unlink (bflag_name);
if (flags) unlink (qflag_file);
exit(1);
}
if (close (fo) == -1)
{
printf ("\nError: Cannot close %s - aborting\n", hold_name);
if (multtsk) unlink (bflag_name);
if (flags) unlink (qflag_file);
exit(1);
}
remove (temp_name); /* delete original file */
}
else /* we can just rename */
{
remove (hold_name); /* be sure to zap filename first */
if (rename (temp_name, hold_name))
{
printf ("\nError: Cannot rename %s - aborting\n", temp_name);
if (multtsk) unlink (bflag_name);
if (flags) unlink (qflag_file);
exit(1);
}
if (inf_level >= 1) /* display area name */
{
printf ("\t-Moving %s [%ldb] -> %s\n", (p+1), abuffer.size, hold_name);
idflag = 1; /* ok to indent */
}
}
/* Create a 0 length file by the same name */
f1 = open (temp_name, O_CREAT|O_TRUNC|O_BINARY|O_RDWR, S_IWRITE);
close (f1);
/* Edit .?LO file to change # to ^ */
if (_dos_findfirst (flo1_name, _A_NORMAL, &fbuffer))
{
printf ("\nError: Could not find .FLO file for %d:%d/%d - continuing\n",
nodes[i].zone, nodes[i].net, nodes[i].node);
if (multtsk) unlink (bflag_name);
if (flags) unlink (qflag_file);
}
else
{ /* process them til finished */
done = 0;
while (!done)
{
if (fbuffer.size > 0)
{
if (myzone != nodes[i].zone)
sprintf (p4, ".%03d\\%s", nodes[i].zone, fbuffer.name);
else
sprintf (p4, "\\%s", fbuffer.name);
if ((f = fopen (flo2_name, "r")) != NULL)
{
j = 0;
while (fgets (send_files[j], 100, f) != NULL)
{
if ((send_files[j][0] == '\n') ||
(send_files[j][0] == '\r') ||
(send_files[j][0] == '\0'))
{
continue;
}
if (send_files[j][0] == '#')
{
_splitpath (&(send_files[j][1]), drive1, dir1, fname1, ext1);
_splitpath (temp_name, drive2, dir2, fname2, ext2);
if ((stricmp (fname1, fname2) == 0) &&
(stricmp (ext1, ext2) == 0))
{
strcpy (&(send_files[j][1]), hold_name);
send_files[j][0] = '^';
strcat (send_files[j], "\n");
}
}
++j;
}
fclose (f);
unlink (flo2_name);
f = fopen (flo2_name, "w");
for (k = 0; k < j; k++)
{
fputs (send_files[k], f);
}
fclose (f);
}
}
if (_dos_findnext (&fbuffer))
done = 1;
}
}
if (multtsk) unlink (bflag_name); /* delete the busy flags */
if (flags) unlink (qflag_file);
/* check the next file for that node number */
if (_dos_findnext (&abuffer))
{
/* if we indented we need to adjust line starting point */
if ((inf_level >= 1) && (idflag == 1))
printf ("\r");
done_node = 1;
}
} /* while (!done_node) */
} /* for */
}